package alo.p4.work;

import java.util.EmptyStackException;

//用一个数组实现三个栈
//保证只有数组有剩余空间，栈操作就不能提示异常
public class ArrayWithThreeStacks {
    private int[] dataArray;
    private int size;
    private int topOne;
    private int topTwo;
    private int baseThree;
    private int topThree;
    public ArrayWithThreeStacks(int size){
        if (size<3) throw new IllegalStateException("size<3 is no persmissible");
        dataArray=new int[size];
        this.size=size;
        topOne=1;
        topTwo=size;
        baseThree=size/2;
        topThree=baseThree;
    }
    public void push(int stackId,int data){
        if (stackId==1){
            if (topOne+1==baseThree){
                if (stack3IsRightShiftable()){
                    shiftStacks3ToRight();
                    dataArray[++topOne]=data;
                }else throw new StackOverflowError("Stack1 has reached max limit");
            }else dataArray[++topOne]=data;
        }else if (stackId==2){
            if (topTwo-1==topThree){
                if (stack3IsLeftShiftable()){
                    shiftStack3ToLeft();
                    dataArray[--topTwo]=data;
                }else throw new StackOverflowError("Stack2 has reached max limit");
            }else dataArray[--topTwo]=data;
        }else if (stackId==3){
            if (topTwo-1==topThree){
                if (stack3IsLeftShiftable()){
                    shiftStack3ToLeft();
                    dataArray[++topThree]=data;
                }else throw new StackOverflowError("Stack3 has reached max limit");
            }else dataArray[++topThree]=data;
        } else return;
    }

    public int pop(int stackId){
        if (stackId==1){
            if (topOne==-1) throw new EmptyStackException();
            int toPop= dataArray[topOne];
            dataArray[topOne--]= Integer.parseInt(null);
            return toPop;
        }else if (stackId==2){
            if (topTwo==this.size) throw new EmptyStackException();
            int toPop= dataArray[topTwo];
            dataArray[topTwo++]= Integer.parseInt(null);
            return toPop;
        }else if (stackId==3){
            if (topThree==this.size&&dataArray[topThree]==Integer.parseInt(null))
                throw new EmptyStackException();
            int toPop=dataArray[topThree];
            if (topThree>=baseThree) dataArray[topThree--]=Integer.parseInt(null);
            if (topThree==baseThree) dataArray[topThree]=Integer.parseInt(null);
            return toPop;
        } else return Integer.parseInt(null);
    }
    public int top(int stackId){
        if (stackId==1){
            if (topOne==-1) throw new EmptyStackException();
                return dataArray[topOne];
        }else if (stackId==2){
            if (topTwo==this.size) throw new EmptyStackException();
            return dataArray[topTwo];
        }else if (stackId==3){
            if (topThree==this.size&&dataArray[topThree]==Integer.parseInt(null))
                throw new EmptyStackException();
            return dataArray[topThree];
        } else return Integer.parseInt(null);
    }
    public boolean isEmpty(int stackId){
        if (stackId==1){
            return topOne==-1;
        }else if (stackId==2) {
            return topTwo == this.size;
        }else if (stackId==3){
            return (topThree==baseThree)&&(dataArray[topThree]==Integer.parseInt(null));
        } else return true;
    }
    //左移判断
    private boolean stack3IsLeftShiftable() {
        if (topOne+1<baseThree) return true;
        return false;
    }
    //左移
    private void shiftStack3ToLeft() {
        for (int i=baseThree-1;i<=topThree;i++){
            dataArray[i]=dataArray[i+1];
        }
        dataArray[topThree--]=Integer.parseInt(null);
        baseThree--;
    }
    //右移判断
    private boolean stack3IsRightShiftable() {
        if (topThree+1<topTwo) return true;
        return false;
    }
    //右移
    private void shiftStacks3ToRight() {
        for (int i=topThree+1;i>=baseThree;i--){
            dataArray[i]=dataArray[i-1];
        }
        dataArray[baseThree++]=Integer.parseInt(null);
        topThree++;

    }
}
